package chances.epg.navigator.service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import chances.epg.commons.log.EpgLogFactory;
import chances.epg.commons.utils.PathUtils;
import chances.epg.commons.utils.URLUtils;
import chances.epg.config.EpgSiteContext;
import chances.epg.data.service.ContentService;
import chances.epg.entity.biz.Biz;
import chances.epg.entity.biz.BizPositionItem;
import chances.epg.entity.content.AlbumItem;
import chances.epg.entity.content.CategoryItem;
import chances.epg.entity.content.Channel;
import chances.epg.entity.content.Episode;
import chances.epg.entity.content.Link;
import chances.epg.entity.content.Program;
import chances.epg.entity.content.Schedule;
import chances.epg.entity.content.SearchContent;
import chances.epg.entity.content.SubjectArea;
import chances.epg.navigator.context.AccessContext;

@Component
public class NavigateUrlFactory {
	
	public static final String VOD_TYPE = "vod";
	public static final String SERIES_TYPE = "series";
	public static final String SERIES2_TYPE = "series2";
	public static final String EPOSIDE_TYPE = "eposide";
	public static final String SUBJECT_TYPE = "subject";
	public static final String ALBUM_TYPE = "album";
	public static final String CHANNEL_TYPE = "channel";
	public static final String SCHEDULE_TYPE = "schedule";

	public static final String ITEM = "item";
	public static final String DETAIL = "det";
	public static final String SCHEDULE = "sch";
	
	public static final String LINK = "link";

	public static final String PLAY = "play";

	public static final String DEFAULT_VALUE = "-";

	public final SimpleDateFormat SIMPLE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
	
	@Value("${epg.url.suffix:.epg}")
	private String suffix;

	@Value("${epg.server.url:http://localhost:8080/epg}")
	private String epgHost;
	
	@Value("${mprogram.site.code:mprogram}")
	private String mprogram;

	@SuppressWarnings("unused")
	@Autowired
	private ContentService contentService;

	/**
	 * 展示栏目链接.
	 * 
	 * @param context
	 * @param biz
	 * @return
	 */
	public String generateURL(AccessContext context, Biz biz) {
		if (context == null) {
			return "";
		}
		return PathUtils.join(context.getEpgSiteContext().getSiteRoot(), biz.getCode() + this.suffix);

	}

	/**
	 * 展示栏目链接.
	 * 
	 * @param context
	 * @param biz
	 * @return
	 */
	public String generateAjaxURL(AccessContext context, String name) {
		if (context == null) {
			return "";
		}
		if (StringUtils.isEmpty(context.getContainerType())||context.getContainerType().equals("-")) {
			return PathUtils.join(context.getEpgSiteContext().getSiteRoot(), context.getBizCode(), "ajax",
					name + this.suffix);
		} else {
			if ("category".equals(context.getContainerType())||"position".equals(context.getContainerType())) {
				return PathUtils.join(context.getEpgSiteContext().getSiteRoot(), context.getBizCode(),
						context.getContainerCode(), "ajax", name + this.suffix);
			}
		}
		return "";

	}

	/**
	 * 展示栏目链接.
	 * 
	 * @param context
	 * @param biz
	 * @return
	 */
	public String generateBizURL(AccessContext context, String bizCode) {
		if (context == null) {
			return "";
		}

		return PathUtils.join(context.getEpgSiteContext().getSiteRoot(), bizCode + this.suffix);

	}

	/**
	 * 编排内容链接.
	 * 
	 * @param context
	 * @param item
	 * @return
	 */
	public String generateURL(AccessContext context, CategoryItem item) {
		if (context == null) {
			return "";
		}
		String url = PathUtils.join(context.getSiteRoot(), context.getBizCode(), AccessContext.CATEGORY_CONTAINER_TYPE,
				item.getCategoryCode(), ITEM, item.getItemType(), item.getId() + this.suffix);

		if (item.isSchedule()) {
			String urlRes = URLUtils.appendParam(url, "reserve", item.getChannelCode());
			urlRes = URLUtils.appendParam(urlRes, "stime", SIMPLE_FORMAT.format(item.getBeginTime()));
			urlRes = URLUtils.appendParam(urlRes, "etime", SIMPLE_FORMAT.format(item.getEndTime()));
			try {
				urlRes = URLUtils.appendParam(urlRes, "title", URLEncoder.encode(item.getTitle(), "UTF-8"));
			} catch (UnsupportedEncodingException e) {
				EpgLogFactory.getSystemLogger().error(e.getMessage());
			}
			//微信节目单直接跳频道详情页
			if(this.suffix.equals(".wx")){
				Schedule schedule = this.contentService.getScheduleByCode(item.getItemCode());
				if(null != schedule){
					urlRes = PathUtils.join(context.getSiteRoot(), context.getBizCode(), AccessContext.CATEGORY_CONTAINER_TYPE,
							item.getCategoryCode(), DETAIL, CHANNEL_TYPE, schedule.getChannelCode() + this.suffix);
				}
			}
			return urlRes;
		} else {
			return url;
		}
	}

	/**
	 * 专栏内容链接.
	 * 
	 * @param context
	 * @param item
	 * @return
	 */
	public String generateURL(AccessContext context, AlbumItem item) {
		if (context == null) {
			return "";
		}

		if (StringUtils.isEmpty(context.getContainerType())) {
			context.setContainerType(DEFAULT_VALUE);
		}
		if (StringUtils.isEmpty(context.getContainerCode())) {
			context.setContainerCode(DEFAULT_VALUE);
		}
		if (StringUtils.isEmpty(context.getContentCode())) {
			context.setContentType(ALBUM_TYPE);
		}
		if (StringUtils.isEmpty(context.getContentCode())) {
			context.setContentCode(item.getAlbumCode());
		}
		if (item.isSeries()) {
			return contentDetailInParent(context, SERIES_TYPE, item.getContentCode());
		} else if (item.isVod()) {
			return contentDetailInParent(context, VOD_TYPE, item.getContentCode());
		} else {
			return "";
		}
	}

	/**
	 * 
	 * @param context
	 * @param subjectArea
	 * @return
	 */
	public String generateURL(AccessContext context, SubjectArea subjectArea) {
		if (context == null) {
			return "";
		}
		if (subjectArea.isPage()) {
			return generatorSubjectPageURL(context, subjectArea.getObjCode());
		} else if (subjectArea.isSeries()) {
			return contentDetailInParent(context, SERIES_TYPE, subjectArea.getObjCode());
		} else if(subjectArea.isSeries2()) {
			return contentDetailInParent(context, SERIES2_TYPE, subjectArea.getObjCode());
		} else if (subjectArea.isVod()) {
			if(subjectArea.isGotoPlay()) {
				Program program = this.contentService.getProrgamByCode(subjectArea.getObjCode());
				return this.generatePlayUrl(context, program);
			} else {
				return contentDetailInParent(context, VOD_TYPE, subjectArea.getObjCode());
			}
		} else if (subjectArea.isBiz()) {
			return generateBizURL(context, subjectArea.getObjCode());
		} else if (subjectArea.isExternalUrl()) {
			return subjectArea.getObjCode();
		} else {
			return "";
		}
	}

	/**
	 * 
	 * @param context
	 * @param position
	 * @return
	 */
	public String generateURL(AccessContext context, BizPositionItem bizPositionItem) {
		if (context == null) {
			return "";
		}
		
		//单集内容直接到播放
		if(bizPositionItem.isVod() && "vodPlay".equals(bizPositionItem.getLinkType())){
			return this.generatePlayUrl(context, bizPositionItem.getObjValue());
		}else{
		    return PathUtils.join(context.getSiteRoot(), context.getBizCode(), AccessContext.POSITION_CONTAINER_TYPE,
				bizPositionItem.getPositionCode(), ITEM, bizPositionItem.getObjType(),
				bizPositionItem.getId() + this.suffix);
		}

	}

	/**
	 * 搜索内容链接.
	 * 
	 * @param context
	 * @param item
	 * @return
	 */
	public String generateURL(AccessContext context, SearchContent content) {
		if (context == null) {
			return "";
		}

		StringBuffer url = new StringBuffer(context.getSiteRoot());
		url.append("/").append(context.getBizCode());

		if (StringUtils.isNotBlank(context.getContainerType())) {
			url.append("/").append(context.getContainerType());
		}

		if (StringUtils.isNotBlank(context.getContainerCode())) {
			url.append("/").append(context.getContainerCode());
		}

		url.append("/").append(DETAIL);

		if (StringUtils.isNotBlank(context.getParentContentType())) {
			url.append("/").append(context.getContentType());
		}

		if (StringUtils.isNotBlank(context.getParentContentCode())) {
			url.append("/").append(context.getContentCode());
		}

		url.append("/").append(content.getType());
		url.append("/").append(content.getCode()).append(this.suffix);
		return url.toString();
	}

	/**
	 * 
	 * @param context
	 * @param content
	 * @return
	 */
	/*
	 * public static String generateURL(AccessContext context,UserContent
	 * ucontent) { StringBuffer url = new
	 * StringBuffer(context.getContextPath());
	 * url.append("/").append(context.getSiteCode());
	 * url.append("/").append(context.getBizCode());
	 * 
	 * if(StringUtils.isNotBlank(context.getContainerType())){
	 * url.append("/").append(context.getContainerType()); }
	 * 
	 * if(StringUtils.isNotBlank(context.getContainerCode())){
	 * url.append("/").append(context.getContainerCode()); }
	 * 
	 * url.append("/").append(DETAIL);
	 * 
	 * if(StringUtils.isNotBlank(context.getParentContentType())){
	 * url.append("/").append(context.getContentType()); }
	 * 
	 * if(StringUtils.isNotBlank(context.getParentContentCode())){
	 * url.append("/").append(context.getContentCode()); }
	 * 
	 * url.append("/").append(ucontent.getContentType().toLowerCase());
	 * url.append("/").append(ucontent.getContentCode()).append(".do"); return
	 * url.toString(); }
	 */

	/**
	 * 
	 * @param context
	 * @param subjectPageCode
	 * @return
	 */
	private String generatorSubjectPageURL(AccessContext context, String subjectPageCode) {
		return this.generateSubjectUrl(context, subjectPageCode);
		//return this.contentDetailInParent(context, subjectPageType, subjectPageCode);
	}

	/**
	 * 
	 * @param context
	 * @param contentType
	 * @param contentCode
	 * @return
	 */
	private String contentDetailInParent(AccessContext context, String contentType, String contentCode) {
		if (context == null) {
			return "";
		}

		if (StringUtils.isEmpty(context.getContainerType())) {
			context.setContainerType(DEFAULT_VALUE);
		}
		if (StringUtils.isEmpty(context.getContainerCode())) {
			context.setContainerCode(DEFAULT_VALUE);
		}
		return PathUtils.join(context.getSiteRoot(), context.getBizCode(), context.getContainerType(),
				context.getContainerCode(), DETAIL, context.getContentType(), context.getContentCode(), contentType,
				contentCode + this.suffix);

	}

	public String generateSchedulePlayURL(AccessContext context, String contentCode) {
		if (context == null) {
			return "";
		}
		return PathUtils.join(context.getSiteRoot(), context.getBizCode(), context.getContainerType(),
				context.getContainerCode(), DETAIL, context.getContentType(), context.getContentCode(),
				contentCode + this.suffix);

	}

	public String generateURL(AccessContext context, Channel channel) {
		if (context == null) {
			return "";
		}

		StringBuffer url = new StringBuffer(context.getSiteRoot());
		url.append("/").append(context.getBizCode());

		if (StringUtils.isNotBlank(context.getContainerType())) {
			url.append("/").append(context.getContainerType());
		}

		if (StringUtils.isNotBlank(context.getContainerCode())) {
			url.append("/").append(context.getContainerCode());
		}

		url.append("/").append(DETAIL);

		if (StringUtils.isNotBlank(context.getParentContentType())) {
			url.append("/").append(context.getContentType());
		}

		if (StringUtils.isNotBlank(context.getParentContentCode())) {
			url.append("/").append(context.getContentCode());
		}

		url.append("/").append(CHANNEL_TYPE);
		url.append("/").append(channel.getContentCode()).append(this.suffix);
		return url.toString();
	}

	public String generateURL(AccessContext context, Schedule schedule) {
		if (context == null) {
			return "";
		}

		StringBuffer url = new StringBuffer(context.getSiteRoot());
		url.append("/").append(context.getBizCode());

		if (StringUtils.isNotBlank(context.getContainerType())) {
			url.append("/").append(context.getContainerType());
		}

		if (StringUtils.isNotBlank(context.getContainerCode())) {
			url.append("/").append(context.getContainerCode());
		}

		url.append("/").append(DETAIL);

		if (StringUtils.isNotBlank(context.getParentContentType())) {
			url.append("/").append(context.getContentType());
		}

		if (StringUtils.isNotBlank(context.getParentContentCode())) {
			url.append("/").append(context.getContentCode());
		}

		url.append("/").append(SCHEDULE_TYPE);
		url.append("/").append(schedule.getCode()).append(this.suffix);
		return url.toString();
	}
	
	public String generatePlayUrl(AccessContext context, String contentCode) {
		StringBuffer url = new StringBuffer(context.getSiteRoot());
		url.append("/").append(context.getBizCode());

		url.append("/").append(PLAY);
		url.append("/").append(VOD_TYPE);
		url.append("/").append(contentCode);
		url.append(this.suffix);
		return url.toString();
	}

	public String generatePlayUrl(AccessContext context, Program program) {
		StringBuffer url = new StringBuffer(context.getSiteRoot());
		url.append("/").append(context.getBizCode());

		url.append("/").append(PLAY);
		url.append("/").append(VOD_TYPE);
		url.append("/").append(program.getContentCode());
		url.append(this.suffix);
		return url.toString();
	}

	public String generatePlayUrl(AccessContext context, Episode episode) {
		StringBuffer url = new StringBuffer(context.getSiteRoot());
		url.append("/").append(context.getBizCode());
		url.append("/").append(PLAY);
		url.append("/").append(SERIES_TYPE);
		url.append("/").append(episode.getSeriesCode());
		url.append("/").append(episode.getContentCode());
		url.append(this.suffix);
		return url.toString();
	}

	public String generatePlayUrl(AccessContext context, Channel channel) {
		StringBuffer url = new StringBuffer(context.getSiteRoot());
		url.append("/").append(context.getBizCode());
		url.append("/").append("play");
		url.append("/").append(CHANNEL_TYPE);
		//url.append("/").append(channel.getContentCode());
		url.append("/").append(channel.getChannelNum());
		url.append(this.suffix);
		return url.toString();
	}

	public String generatePlayUrl(AccessContext context, Schedule schedule) {
		SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss");

		StringBuffer url = new StringBuffer(context.getSiteRoot());
		url.append("/").append(context.getSiteCode());
		url.append("/").append(context.getBizCode());

		if (StringUtils.isEmpty(context.getContainerType())) {
			url.append("/").append(DEFAULT_VALUE);
		} else {
			url.append("/").append(context.getContainerType());
		}

		if (StringUtils.isEmpty(context.getContainerCode())) {
			url.append("/").append(DEFAULT_VALUE);
		} else {
			url.append("/").append(context.getContainerCode());
		}

		if (StringUtils.isEmpty(context.getParentContentType())) {
			url.append("/").append(DEFAULT_VALUE);
		} else {
			url.append("/").append(context.getParentContentType());
		}

		if (StringUtils.isEmpty(context.getParentContentCode())) {
			url.append("/").append(DEFAULT_VALUE);
		} else {
			url.append("/").append(context.getParentContentCode());
		}
		url.append("/").append(SCHEDULE);
		url.append("/").append(schedule.getChannelCode());
		url.append(this.suffix);
		url.append("?beginTime=").append(yyyyMMddHHmmss.format(schedule.getStartTime()));
		url.append("&endTime=").append(yyyyMMddHHmmss.format(schedule.getEndTime()));
		return url.toString();
	}

	public String generateLoginUrl(EpgSiteContext epgSiteContext) {
		return PathUtils.join(epgSiteContext.getContextPath(), epgSiteContext.getSiteCode(), "logon" + this.suffix);
	}

	public String generateDefaultUrl(EpgSiteContext epgSiteContext) {
		return PathUtils.join(epgSiteContext.getContextPath(), epgSiteContext.getSiteCode(), "index" + this.suffix);
	}

	public String generatePlayBackUrl(AccessContext accessContext,String userId) {
		EpgSiteContext epgSiteContext = accessContext.getEpgSiteContext();
		return PathUtils.join(epgHost, epgSiteContext.getSiteCode(), accessContext.getBizCode(),
				"playback" ,userId+ this.suffix);
	}

	public String generateSubjectUrl(AccessContext accessContext, String pageCode) {
		EpgSiteContext epgSiteContext = accessContext.getEpgSiteContext();
		return this.contentDetailInParent(accessContext, SUBJECT_TYPE, pageCode);
	}

	/**
	 * 生成节目筛选链接
	 * @param context
	 * @param obj
	 * @return
	 */
	public String generateSearchFilterURL(AccessContext context, Map<String, Object> item) {
		if (context == null) {
			return "";
		}
		String categoryCode = context.getContainerCode();
		if(StringUtils.isEmpty(categoryCode)) {
			categoryCode = "-";
		}
		String url = PathUtils.join(context.getSiteRoot(), context.getBizCode(), AccessContext.CATEGORY_CONTAINER_TYPE,
				categoryCode, DETAIL, item.get("type") + "", item.get("contentCode") + this.suffix);
		return url;
	}

	/**
	 * 生成外链链接
	 * 
	 * @param context
	 * @param link
	 * @return
	 */
	public String generateLinkUrl(AccessContext context, Link link) {
		if (context == null) {
			return "";
		}
		String url = PathUtils.join(context.getSiteRoot(), context.getBizCode(),
				AccessContext.CATEGORY_CONTAINER_TYPE, context.getContainerCode(),
				LINK, link.getCode() + this.suffix);
		return url;
	}

	public String getMprogram() {
		return mprogram;
	}

	public void setMprogram(String mprogram) {
		this.mprogram = mprogram;
	}
	
}
